{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf330
{\fonttbl\f0\fnil\fcharset0 Monaco;}
{\colortbl;\red255\green255\blue255;\red191\green0\blue0;\red0\green0\blue191;\red96\green96\blue96;
}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural

\f0\fs18 \cf0 \
\cf2 // General Setup -- Do this first!\cf0 \
(\
~numberOfChannels = 8;\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf3 Server\cf0 .local.options.numInputBusChannels = ~numberOfChannels;\
\cf3 Server\cf0 .local.options.numOutputBusChannels = ~numberOfChannels;\
\cf3 Server\cf0 .local.options.device = \cf4 "Zirkonium"\cf0 ;\
)\
\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf2 // Start Zirkonium, then launch Audio MIDI Setup and select Zirkonium as the \cf0 \
\cf2 // Standard Input and Output. Then boot a server and run the following.\cf0 \
\
\
\cf2 //\cf0 \
\cf2 //	Audio\cf0 \
\cf2 //\cf0 \
\cf2 //	Generate the audio that can be panned by Zirkonium. This example generates 8 channels of audio.\cf0 \
\cf2 // 	The Zirkonium Device can accept up to 16 audio channels.\cf0 \
\cf2 //\cf0 \
(\
\{ \
	\cf3 var\cf0  noise, numChannels, numChannelsOver2;\
	numChannels = ~numberOfChannels;\
	numChannelsOver2 = (numChannels/2).asInteger;\
	noise = \cf3 PinkNoise\cf0 .ar(\cf3 Array\cf0 .fill(numChannels, 0.005));\
	\cf3 Ringz\cf0 .ar(noise, \cf3 Harmonics\cf0 (numChannelsOver2).rand(50, 400) ++ \cf3 Harmonics\cf0 (numChannels - numChannelsOver2).rand(400, 800), \cf3 Harmonics\cf0 (numChannels).rand(1, 2));\
\}.play\
)\
\
\
\
\
\cf2 //\cf0 \
\cf2 // 	Control Example 1 -- Spherical Coordinates\cf0 \
\cf2 //\cf0 \
\cf2 //	Control the positions of the 8 channels from SuperCollider. This example uses the\cf0 \
\cf2 //	"/pan/az" command which takes coordinates in spherical form. \cf0 \
\cf2 //\cf0 \
\cf2 // 	Compare to the other control examples. See the Zirkonium documentation \cf0 \
\cf2 // 	for more information about the OSC interface.\cf0 \
\cf2 //  	\cf0 \
(\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf3 var\cf0  slider;\
\cf3 var\cf0  text;\
\cf3 var\cf0  panCtl;\
\cf3 var\cf0  azSpan = 0.0, znSpan = 0.0;\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf2 //azSpan = 0.1;\cf0 \
\cf2 //znSpan = 0.1;\cf0 \
\
	\cf2 // Connection to Zirkonium\cf0 \
z = \cf3 NetAddr\cf0 (\cf4 "localhost"\cf0 , 50808);\
\
w = \cf3 SCWindow\cf0 (\cf4 "Dome"\cf0 , \cf3 Rect\cf0 (128, 128, 400, 256));\
w.front;\
slider = \cf3 SC2DSlider\cf0 (w, \cf3 Rect\cf0 (10, 10, 200, 200));\
slider.x = 0.5;\
slider.y = 0.0;\
slider.action = \{ \cf3 arg\cf0  widget; panCtl.value(widget.x, widget.y) \};\
\
panCtl = \{ \cf3 arg\cf0  x, y;\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\cf0 	\cf3 var\cf0  panx, pany;\
	\cf3 var\cf0  polar;\
	\cf3 var\cf0  zenith, azimuth;\
	\cf3 var\cf0  dazimuth;\
	\cf3 var\cf0  numChannels = 8;\
	\cf3 var\cf0  panCommands;\
	\
		\cf2 // X and Y are swapped in Zirkonium (X is height)\cf0 \
	panx = y; pany = x;\
	\
		\cf2 // [0, 0] needs to be in the middle\cf0 \
	panx = (panx - 0.5) * 2.0;\
	pany = 1.0 - pany;\
	pany = (pany - 0.5) * 2.0;\
	polar = \cf3 Point\cf0 (panx, pany).asPolar;\
	\
		\cf2 // Project onto the surface of a sphere\cf0 \
	zenith = (0.5 - (polar.rho * 0.5)).max(0.0);\
	azimuth = polar.theta / 3.141593;\
\
	\cf2 // DEBUG	\cf0 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\cf2 //	[azimuth, zenith].postln;\cf0 \
	panCommands = \cf3 List\cf0 .new;\
	dazimuth = 2.0 / numChannels;\
	numChannels.do \{ \cf3 arg\cf0  i; panCommands.add([\cf4 "/pan/az"\cf0 , i, azimuth + (i * dazimuth), zenith, azSpan, znSpan, 1.0]) \};\
	z.sendBundle(0.0, *panCommands);\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf0 \};\
)\
\
\
\
\
\cf2 //\cf0 \
\cf2 // 	Control Example 2 -- Speakers (Azimuth / Zenith)\cf0 \
\cf2 //\cf0 \
\cf2 //	Control the positions of the 2 of the 8 channels from SuperCollider. This example uses the\cf0 \
\cf2 //	"/pan/speaker/az" command which takes a coordinates in spherical formant moves the ID to the\cf0 \
\cf2 // 	speaker nearest the specified position.\cf0 \
\cf2 //\cf0 \
\cf2 // 	Compare to the other control examples. See the Zirkonium documentation \cf0 \
\cf2 // 	for more information about the OSC interface.\cf0 \
\cf2 //  	\cf0 \
(\
z = \cf3 NetAddr\cf0 (\cf4 "localhost"\cf0 , 50808);\
z.sendMsg(\cf4 "/pan/speaker/az"\cf0 , 0, 0.1, 0.1, 1.0);\
z.sendMsg(\cf4 "/pan/speaker/az"\cf0 , 1, 0.7, 0.0, 1.0);\
)\
\
\
\
\
\cf2 //\cf0 \
\cf2 // 	Control Example 3 -- Speakers (X/ Y)\cf0 \
\cf2 //\cf0 \
\cf2 //	Control the positions of the 2 of the 8 channels from SuperCollider. This example uses the\cf0 \
\cf2 //	"/pan/speaker/xy" command which takes a coordinates in cartesian formant moves the ID to the\cf0 \
\cf2 // 	speaker nearest the specified position.\cf0 \
\cf2 //\cf0 \
\cf2 // 	Compare to the other control examples. See the Zirkonium documentation \cf0 \
\cf2 // 	for more information about the OSC interface.\cf0 \
\cf2 //  	\cf0 \
(\
z = \cf3 NetAddr\cf0 (\cf4 "localhost"\cf0 , 50808);\
z.sendMsg(\cf4 "/pan/speaker/xy"\cf0 , 0, 0.3, 0.3, 1.0);\
z.sendMsg(\cf4 "/pan/speaker/xy"\cf0 , 1, -0.4, -0.4, 1.0);\
)\
\
\
\
\
\cf2 //\cf0 \
\cf2 // 	Control Example 4 -- Cartesian\cf0 \
\cf2 //\cf0 \
\cf2 //	Control the positions of the channel 1 from SuperCollider. This example uses the\cf0 \
\cf2 //	"/pan/xy" command which takes a coordinates in cartesian form.\cf0 \
\cf2 //\cf0 \
\cf2 // 	Compare to the other control examples. See the Zirkonium documentation \cf0 \
\cf2 // 	for more information about the OSC interface.\cf0 \
\cf2 //  	\cf0 \
(\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf3 var\cf0  slider;\
\cf3 var\cf0  text;\
\cf3 var\cf0  panCtl;\
\
	\cf2 // Connection to Zirkonium\cf0 \
z = \cf3 NetAddr\cf0 (\cf4 "localhost"\cf0 , 50808);\
\
w = \cf3 SCWindow\cf0 (\cf4 "Dome"\cf0 , \cf3 Rect\cf0 (128, 128, 400, 256));\
w.front;\
slider = \cf3 SC2DSlider\cf0 (w, \cf3 Rect\cf0 (10, 10, 200, 200));\
slider.x = 0.5;\
slider.y = 0.0;\
slider.action = \{ \cf3 arg\cf0  widget; panCtl.value(widget.x, widget.y) \};\
\
panCtl = \{ \cf3 arg\cf0  x, y;\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\cf0 	\cf3 var\cf0  panx, pany;\
	\
		\cf2 // X and Y are swapped in Zirkonium (X is height)\cf0 \
	panx = y; pany = x;\
	\
		\cf2 // [0, 0] needs to be in the middle\cf0 \
	panx = (panx - 0.5) * 2.0;\
	pany = 1.0 - pany;\
	pany = (pany - 0.5) * 2.0;\
\
	z.sendMsg(\cf4 "/pan/xy"\cf0 , 0, panx, pany, 0.3, 0.3, 1.0);\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf0 \};\
)\
\
\cf2 //\cf0 \
\cf2 // 	Control Example 5 -- Device\cf0 \
\cf2 //\cf0 \
\cf2 //   Normally, OSC commands to Zirkonium are routed to the frontmost window, but it is\cf0 \
\cf2 //   possible to address a specific window or the device by specifying that in the OSC command.\cf0 \
\cf2 //\cf0 \
\cf2 //   Compare to Example 1.\cf0 \
\cf2 //  	\cf0 \
(\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf3 var\cf0  slider;\
\cf3 var\cf0  text;\
\cf3 var\cf0  panCtl;\
\cf3 var\cf0  azSpan = 0.0, znSpan = 0.0;\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf2 //azSpan = 0.1;\cf0 \
\cf2 //znSpan = 0.1;\cf0 \
\
	\cf2 // Connection to Zirkonium\cf0 \
z = \cf3 NetAddr\cf0 (\cf4 "localhost"\cf0 , 50808);\
\
w = \cf3 SCWindow\cf0 (\cf4 "Dome"\cf0 , \cf3 Rect\cf0 (128, 128, 400, 256));\
w.front;\
slider = \cf3 SC2DSlider\cf0 (w, \cf3 Rect\cf0 (10, 10, 200, 200));\
slider.x = 0.5;\
slider.y = 0.0;\
slider.action = \{ \cf3 arg\cf0  widget; panCtl.value(widget.x, widget.y) \};\
\
panCtl = \{ \cf3 arg\cf0  x, y;\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\cf0 	\cf3 var\cf0  panx, pany;\
	\cf3 var\cf0  polar;\
	\cf3 var\cf0  zenith, azimuth;\
	\cf3 var\cf0  dazimuth;\
	\cf3 var\cf0  numChannels = 8;\
	\cf3 var\cf0  panCommands;\
	\
		\cf2 // X and Y are swapped in Zirkonium (X is height)\cf0 \
	panx = y; pany = x;\
	\
		\cf2 // [0, 0] needs to be in the middle\cf0 \
	panx = (panx - 0.5) * 2.0;\
	pany = 1.0 - pany;\
	pany = (pany - 0.5) * 2.0;\
	polar = \cf3 Point\cf0 (panx, pany).asPolar;\
	\
		\cf2 // Project onto the surface of a sphere\cf0 \
	zenith = (0.5 - (polar.rho * 0.5)).max(0.0);\
	azimuth = polar.theta / 3.141593;\
\
	\cf2 // DEBUG	\cf0 \
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
\cf2 //	[azimuth, zenith].postln;\cf0 \
	panCommands = \cf3 List\cf0 .new;\
	dazimuth = 2.0 / numChannels;\
	numChannels.do \{ \cf3 arg\cf0  i; panCommands.add([\cf4 "/pan/az"\cf0 , i, azimuth + (i * dazimuth), zenith, azSpan, znSpan, 1.0, \cf4 "__device__"\cf0 ]) \};\
	z.sendBundle(0.0, *panCommands);\
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\cf0 \};\
)\
\
\cf2 //\cf0 \
\cf2 // 	Control Example 6 -- Master Gain\cf0 \
\cf2 //\cf0 \
\cf2 //   It is also possible to control the master gain via OSC. This changes the gain, but it is not\
//   reflected in Zirkonium's Perferences display because it does not change the preference.\cf0 \
\cf2 //  \cf0 \
(\
	\cf2 // Connection to Zirkonium\cf0 \
z = \cf3 NetAddr\cf0 (\cf4 "localhost"\cf0 , 50808);\
z.sendMsg("/master/gain", 0.5);\
)}